package com.pxmeta.user.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pxmeta.circle.service.IUserCircleService;
import com.pxmeta.common.exception.ServiceException;
import com.pxmeta.user.entity.SignConfig;
import com.pxmeta.user.entity.UserSignRecord;
import com.pxmeta.user.mapper.UserSignRecordMapper;
import com.pxmeta.user.service.ISignConfigService;
import com.pxmeta.user.service.IUserSignRecordService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.time.LocalDate;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wcl
 * @since 2022-07-13
 */
@Service
@RequiredArgsConstructor
public class UserSignRecordServiceImpl extends ServiceImpl<UserSignRecordMapper, UserSignRecord> implements IUserSignRecordService {
    private final IUserCircleService userCircleService;
    private final ISignConfigService signConfigService;

    @Override
    @Transactional
    public void signInCircle(Long circleId, Long userId) {
        //查询当前用户今日是否已签到
        LocalDate now = LocalDate.now();
        Boolean signStatus = getSignStatus(circleId, userId, 1);
        if (signStatus){
            throw new ServiceException("今日已签到，无需重复签到！");
        }
        UserSignRecord saveRecord = new UserSignRecord();
        saveRecord.setUserId(userId);
        saveRecord.setCircleId(circleId);
        saveRecord.setSignTime(now);
        saveRecord.setSignType(1);
        saveRecord.setSignReward("5经验值");
        this.save(saveRecord);

        userCircleService.addExp(userId,circleId,5);
    }

    @Override
    public void signInSystem(Long circleId, Long userId, Integer rewardId) {
        //查询当前用户今日是否已签到
        LocalDate now = LocalDate.now();
        Boolean signStatus = getSignStatus(circleId, userId, 2);
        if (signStatus){
            throw new ServiceException("今日已签到，无需重复签到！");
        }

        SignConfig config = signConfigService.getById(rewardId);

        if ( null == config){
            throw new ServiceException("奖励不存在！");
        }

        Integer count = config.getCount();
        String reward = config.getReward();
        UserSignRecord saveRecord = new UserSignRecord();
        saveRecord.setUserId(userId);
        saveRecord.setCircleId(circleId);
        saveRecord.setSignTime(now);
        saveRecord.setSignType(2);
        saveRecord.setSignReward(String.format("%s %s",count, reward));
        this.save(saveRecord);

    }


    @Override
    public Boolean getSignStatus(Long circleId, Long userId, Integer type) {
        LocalDate now = LocalDate.now();
        LambdaQueryWrapper<UserSignRecord> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(UserSignRecord::getCircleId, circleId)
                .eq(UserSignRecord::getUserId, userId)
                .eq(UserSignRecord::getSignType, type)
                .eq(UserSignRecord::getSignTime, now);
        UserSignRecord record = this.getOne(wrapper);
        return record != null;
    }

    /**
     * 获取当前时间所在周的周一和周日的日期时间
     *
     * @return
     */
    private static Map<String, String> getWeekDate() {
        Map<String, String> map = new HashMap();
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar cal = Calendar.getInstance();
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayWeek == 1) {
            dayWeek = 8;
        }

        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        Date mondayDate = cal.getTime();

        cal.add(Calendar.DATE, 4 + cal.getFirstDayOfWeek());
        Date sundayDate = cal.getTime();


        map.put("mondayDate", DateUtil.format(mondayDate,"yyyy-MM-dd"));
        map.put("sundayDate", DateUtil.format(sundayDate,"yyyy-MM-dd"));
        return map;
    }


    @Override
    public List<SignConfig> listReward(Long userId) {


        Map<String, String> weekDate = getWeekDate();
        String mondayDate = weekDate.get("mondayDate");
        String sundayDate = weekDate.get("sundayDate");

        //查询这周签到的记录。
        LambdaQueryWrapper<UserSignRecord> recordWrapper = Wrappers.lambdaQuery();
        recordWrapper.eq(UserSignRecord::getUserId, userId)
                .ge(UserSignRecord::getSignTime,mondayDate)
                .le(UserSignRecord::getSignTime, sundayDate);

        List<UserSignRecord> recordList = this.list(recordWrapper);

        LambdaQueryWrapper<SignConfig> wrapper = Wrappers.lambdaQuery();
        wrapper.orderByAsc(SignConfig::getDayCount);

        List<SignConfig> rewardList = signConfigService.list(wrapper);

        for (int i = 0; i < recordList.size(); i++) {
            SignConfig signConfig = rewardList.get(i);
            signConfig.setIsSign(true);
        }

        return rewardList;
    }
}
